Software developers occasionally discover minor errors in previously released programs. Furthermore, incompatibilities between an old program and a new operating system arise when a user updates an operating system. New computer hardware can also result in the discovery of errors in software designed to run on a previously existing hardware platform. Recalling entire programs can be very costly and impractical in cases where the error is relatively minor and/or the number of distributed programs is relatively large. In such instances downloadable software patches offer a practical tool for inserting replacement instructions or data enabling the software to operating properly. Software patches in many instances modify the operation of, or add functionality to, a program to improve operation of the program. Thus, if a software developer, user or other party identifies a bug or other needed fix in an existing computer program, then the developer distributes a patch for insertion by a user into the computer program to remedy the incompatibility.
Such installed patches in many instances take the form of permanent patches. Installing a permanent patch within a program modifies the program such that changes are stored within the executable code itself. In addition to the changes within the code itself, a permanent patch may reference an externally stored patch routine or function. For example, a program is modified to reference a replacement DLL by changing an address in the import section.
A permanent patch may take the form of replacement bytes inserted directly into the prior version of the program. Alternatively the permanent patch consists of a “hook” inserted into the prior version of the program to call an outside routine or function. The programming technique of “hooking” thus comprises identifying problematic program segments and then injecting substitute or additional executable instructions into the executable program to remedy the problem. In the case of API hooking, this patching procedure involves identifying a particular segment of code for calling an API that results in undesirable program behavior. Next, substitute code is placed before, or in place of, the problematic API call. The substitute code invokes execution of referenced substitute program segments. Permanent patches are relatively easy to carry out. However, in many instances this technique cannot be used. Examples of such instances are discussed herein below.
A first instance where a permanent patch cannot easily be incorporated into a program is non-universal changes to an operating system. Software patches are not limited to executable programs. In some instances operating system software is patched. Permanent patches are inserted into the operating system to remedy universal errors (i.e., errors generally associated with all uses of the operating system program). The permanent patch to the operating system software must be compatible with other existing programs. Otherwise, the permanent patch creates new errors requiring further patches.
In a second instance where permanent patches cannot be utilized is for programs that do not permit changes to their code. Since a computer program must permit changes to its original code to implement a permanent patch, programs that are stored upon, and executed from, read only memory media cannot be fixed via permanent patches. Furthermore, a number of computer-based video games include anti-tampering mechanisms preventing changes to either the computer instructions or data. The anti-tampering mechanisms ensure proper use and operation of the programs, but they also prevent applying permanent software patches. Since a permanent patch necessitates changing a computer program's code, software with anti-tampering mechanisms are unlikely to allow even relatively minor permanent software patches. In such instances, installing a software patch requires disabling the anti-tampering mechanisms of a computer program. Thus, when faced with a need to make even minor changes to a tamper-protected program, developers either issue entire new copies of a program in an updated form or disable the anti-tampering mechanisms.
One way to patch programs having anti-tampering mechanisms is to change a set of operating system APIs (application program interfaces) called by the program rather than the program itself. Anti-tampering mechanisms are unlikely to detect changes to the APIs. For example, many programs include a “get version” operating system command/API enabling applications to determine the version of an operating system installed upon a computer system upon which the executable programs execute. A computer program executing on a computer running a new version of an operating system will determine that the version of the operating system is unknown. The computer program registers an error condition and prevents further program execution. However, in many instances a computer program's operation is unaffected by changes present in the new operating system, and a simple incompatibility is eliminated by installing a patch in the API causing issuance of an expected prior) version identification when the program executes the “get version” command. Such a fix does not require modifications to the computer program itself, and therefore anti-tampering safeguards are unaffected by such a patch. The drawback to changing such APIs permanently is, as mentioned above, the potential errors arising from the changes to the APIs when other programs are executed.
There exists a need to make changes to a program in a manner that does not interfere with the operation of other, properly functioning programs, is transparent to users, and does not invoke software protection mechanisms built into programs to prevent unauthorized modifications.